#include <cuda.h>
#include <stdio.h>

void dump_uuid(cudaUUID_t uuid) {
	unsigned char* bytes = reinterpret_cast<unsigned char *>(&uuid);

	printf("cuda uuid: ");
	for (int i = 0; i < sizeof(cudaUUID_t); i++) {
		printf("%02X", bytes[i]);
		if ((i + 1) % 4 == 0) {
			printf(" ");
		}
	}

	printf("\n");
}

int main(int argc, char** argv) {

	struct cudaDeviceProp p;
	int device;
	int device_cnt = -1;

	cudaGetDevice(&device);
	cudaGetDeviceCount(&device_cnt);
	cudaGetDeviceProperties(&p, device);

	printf("device count: %d\n", device_cnt);
	printf("device name: %s\n", p.name);
	printf("cuda uuid size: %ld\n", sizeof(cudaUUID_t));
	dump_uuid(p.uuid);
	printf("totalGlobalMem: %ldM\n", p.totalGlobalMem/1024/1024);
	printf("sharedMemPerBlock: %ldK\n", p.sharedMemPerBlock/1024);
	printf("regsPerBlock: %d\n", p.regsPerBlock);
	printf("warpSize: %d threads\n", p.warpSize);
	printf("memPitch: %ld B\n", p.memPitch);
	printf("maxThreadsPerBlock: %d\n", p.maxThreadsPerBlock);
	printf("maxThreadsDim: (%d, %d, %d)\n", p.maxThreadsDim[0], p.maxThreadsDim[1], p.maxThreadsDim[2]);
	printf("maxGridSize: (%d, %d, %d)\n", p.maxGridSize[0], p.maxGridSize[1], p.maxGridSize[2]);
	printf("totalConstMem: %ld B\n", p.totalConstMem);
	printf("Compute Capability: %d.%d\n", p.major, p.minor);
	printf("clockRate: %d kHz\n", p.clockRate);
	printf("textureAlignment: %ld\n", p.textureAlignment);
	printf("deviceOverlap: %d\n", p.deviceOverlap);
	printf("multiProcessorCount: %d\n", p.multiProcessorCount);
	printf("kernelExecTimeoutEnabled: %d\n", p.kernelExecTimeoutEnabled);
	printf("integrated: %d\n", p.integrated);
	printf("canMapHostMemory: %d\n", p.canMapHostMemory);
	printf("computeMode: %d\n", p.computeMode);
	printf("maxTexture1D: %d\n", p.maxTexture1D);
	printf("maxTexture2D: (%d, %d)\n", p.maxTexture2D[0], p.maxTexture2D[1]);
	printf("maxTexture3D: (%d, %d, %d)\n", p.maxTexture3D[0], p.maxTexture3D[1], p.maxTexture3D[2]);
	printf("maxTexture1DLayered: (%d, %d)\n", p.maxTexture1DLayered[0], p.maxTexture1DLayered[1]);
	printf("maxTexture2DLayered: (%d, %d, %d)\n", p.maxTexture2DLayered[0], p.maxTexture2DLayered[1], p.maxTexture2DLayered[2]);
	printf("surfaceAlignment: %ld\n", p.surfaceAlignment);
	printf("concurrentKernels: %d\n", p.concurrentKernels);
	printf("ECCEnabled: %d\n", p.ECCEnabled);
	printf("PCI Bus ID: %d:%d.%d\n", p.pciBusID, p.pciDeviceID, p.pciDomainID);
	printf("tccDriver: %d\n", p.tccDriver);
	printf("asyncEngineCount: %d\n", p.asyncEngineCount);
	printf("unifiedAddressing: %d\n", p.unifiedAddressing);
	printf("memoryClockRate: %d kHz\n", p.memoryClockRate);
	printf("memoryBusWidth: %d bits\n", p.memoryBusWidth);
	printf("l2CacheSize: %d B\n", p.l2CacheSize);
	printf("maxThreadsPerMultiProcessor: %d\n", p.maxThreadsPerMultiProcessor);

	return 0;
}
